home *** CD-ROM | disk | FTP | other *** search
- /*
- linfit(XYpoints)
- Fit data to a straight line using linear regression formula.
- */
-
- /* This file uses the "no globals" version of callbacks.
- (PC relative strings). */
-
- #include "callback.h" /* use "no global" version of callbacks */
-
- /* can't use math library sqrt() without A4 globals so implement a sqrt() here
- via FixMath toolbox call. Works only for .5 < x < 1e6 */
- double sqrt(double x);
- double sqrt(double x)
- {
- return 1/Frac2X(FracSqrt(X2Frac(1/x)));
- }
-
- static short linfit(double *retval,funptr callback)
- {
- EXPR arr;
- double x,y,*iptr,*jptr,intercept;
- double sumx,sumxx,sumy,sumyy,sumxy,Sxx,Sxy;
- short isarray;
- long n,count;
-
- sumx=0; sumxx=0; sumy=0; sumyy=0; sumxy=0;
- n = 0;
- MakeParmExpr(0,&arr,callback);
- ProbeExpr(arr,&x,&isarray,&count,callback);
- if(!isarray || count<2)
- {
- ErrMsg(" linfit() expects array of {x,y}",0L,callback);
- FreeExpr(arr,callback);
- return(FALSE);
- }
- AddIndex(&arr,&iptr,callback); // arr[i] is {x,y}
- AddIndex(&arr,&jptr,callback); // j picks x or y
- while(count--)
- {
- *jptr = 1;
- if(EvalExpr(arr,&x,callback) && x==x)
- {
- *jptr = 2;
- if(EvalExpr(arr,&y,callback) && y==y)
- {
- sumx += x;
- sumxx += x*x;
- sumy += y;
- sumyy += y*y;
- sumxy += x*y;
- n++;
- }
- }
- *iptr += 1;
- }
- Sxx=n*sumxx-sumx*sumx;
- Sxy=n*sumxy-sumx*sumy;
-
- SetVarVal("slope",Sxy/Sxx,callback);
- intercept=(sumxx*sumy-sumx*sumxy)/(n*sumxx-sumx*sumx);
- SetVarVal("intercept",intercept,callback);
- *retval = Sxy/sqrt(Sxx*(n*sumyy-sumy*sumy)); // return correlation coeff
-
- FreeExpr(arr,callback);
- return(TRUE);
- }
-
- void main(funptr callback)
- {
- AddXfun("linfit","XYpoints",&linfit,NULL,callback);
- }
-